---
title: Nested Menu
description: Using the menu machine for nested menus in your project.
package: "@zag-js/menu"
slugAlias: "menu"
---

An accessible dropdown and context menu that is used to display a list of
actions or options that a user can choose.

<Resources pkg="@zag-js/menu" />

<Showcase id="NestedMenu" />

**Features**

- Support for items, labels, groups of items
- Focus is fully managed using `aria-activedescendant` pattern
- Typeahead to allow focusing items by typing text
- Keyboard navigation support including arrow keys, home/end, page up/down

## Installation

To use the menu machine in your project, run the following command in your
command line:

<CodeSnippet id="menu/installation.mdx" />

## Anatomy

To set up the menu correctly, you'll need to understand its anatomy and how we
name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="menu" />

## Usage

First, import the menu package into your project

```jsx
import * as menu from "@zag-js/menu"
```

The menu package exports two key functions:

- `machine` — The state machine logic for the menu widget.
- `connect` — The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll need to provide a unique `id` to the `useMachine` hook. This is used to
> ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
menu machine in your project 🔥

- Destructure the machine's **service** returned from the `useMachine` hook.
- Use the exposed `setParent` and `setChild` functions provided by the menu's
  connect function to assign the parent and child menus respectively.
- Create trigger item's using the `api.getTriggerItemProps(...)` function.

When building nested menus, you'll need to use:

- `setParent(...)` — Function to register a parent menu's machine in the child
  menu's context.
- `setChild(...)` — Function to register a child menu's machine in the parent
  menu's context.

<CodeSnippet id="menu/nested-menu.mdx" />

## Styling guide

Earlier, we mentioned that each menu part has a `data-part` attribute added to
them to select and style them in the DOM.

### Highlighted item state

When an item is highlighted, via keyboard navigation or pointer, it is given a
`data-highlighted` attribute.

```css
[data-part="item"][data-highlighted] {
  /* styles for highlighted state */
}

[data-part="item"][data-type="radio|checkbox"][data-highlighted] {
  /* styles for highlighted state */
}
```

### Disabled item state

When an item or an option item is disabled, it is given a `data-disabled`
attribute.

```css
[data-part="item"][data-disabled] {
  /* styles for disabled state */
}

[data-part="item"][data-type="radio|checkbox"][data-disabled] {
  /* styles for disabled state */
}
```

### Using arrows

When using arrows within the menu, you can style it using css variables.

```css
[data-part="arrow"] {
  --arrow-size: 20px;
  --arrow-background: red;
}
```

### Checked option item state

When an option item is checked, it is given a `data-state` attribute.

```css
[data-part="item"][data-type="radio|checkbox"][data-state="checked"] {
  /* styles for checked state */
}
```

## Methods and Properties

### Machine Context

The menu machine exposes the following context properties:

<ContextTable name="menu" />

### Machine API

The menu `api` exposes the following methods:

<ApiTable name="menu" />

### Data Attributes

<DataAttrTable name="menu" />

### CSS Variables

<CssVarTable name="menu" />

## Accessibility

Uses
[aria-activedescendant](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-actions-active-descendant/)
pattern to manage focus movement among menu items.

### Keyboard Interactions

<KeyboardTable name="nested-menu" />
